// WebMonitorSDK.ts - Web Monitor SDK 主类
// @/utils/monitor/WebMonitorSDK.ts

import { 
  MonitorConfig, 
  MonitorEvent, 
  EventType, 
  IMonitor,
  ErrorEventData,
  CustomEventData 
} from './MonitorTypes';

// 导入统一的监控事件总线
import { MonitorEventBus, getMonitorEventBus } from './core/MonitorEventBus';
// 导入采集器
import { ErrorCollector } from './collectors/ErrorCollector';
import { PerformanceCollector } from './collectors/PerformanceCollector';
import { NetworkCollector } from './collectors/NetworkCollector';
import { BehaviorCollector } from './collectors/BehaviorCollector';
// 导入上报器
import { Reporter } from './reporter/Reporter';
// 导入工具
import { generateSessionId } from './utils/uuid';
import { getEventContext } from './utils/context';

/**
 * Web Monitor SDK 主类
 * 单例模式管理整个监控系统
 */
export class WebMonitorSDK implements IMonitor {
  private static instance: WebMonitorSDK;
  private config!: MonitorConfig;
  private sessionId: string;
  private eventBus: MonitorEventBus; // 使用统一的监控事件总线
  private reporter: Reporter | undefined;
  private collectors: Map<string, any>;
  private initialized: boolean = false;

  private constructor() {
    this.sessionId = generateSessionId(); // 使用工具类生成会话ID
    this.eventBus = getMonitorEventBus(); // 使用统一事件总线
    this.collectors = new Map();
  }

  /**
   * 获取SDK单例实例
   */
  public static getInstance(): WebMonitorSDK {
    if (!WebMonitorSDK.instance) {
      WebMonitorSDK.instance = new WebMonitorSDK();
    }
    return WebMonitorSDK.instance;
  }

  /**
   * 初始化SDK
   */
  public init(config: MonitorConfig): void {
    if (this.initialized) {
      console.warn('WebMonitorSDK already initialized');
      return;
    }

    this.config = this.validateConfig(config);
    
    // 设置事件总线调试模式
    this.eventBus.setDebug(this.config.enableDebug);
    
    // 初始化上报器
    this.reporter = new Reporter(this.config, this.eventBus);
    this.reporter.start();

    if (this.config.enableAutoTrack) {
      this.setupCollectors();
    }

    this.setupEventListeners();
    this.initialized = true;

    if (this.config.enableDebug) {
      console.log('WebMonitorSDK initialized', this.config);
      console.log('EventBus stats:', this.eventBus.getEventStats());
    }
  }

  /**
   * 验证和设置默认配置
   */
  private validateConfig(config: MonitorConfig): MonitorConfig {
    const defaultConfig: Partial<MonitorConfig> = {
      enableAutoTrack: true,
      sampleRate: 1,
      maxBatchSize: 20,
      flushInterval: 10000,
      maxRetries: 3,
      enableDebug: false
    };

    // 验证必填项
    if (!config.appId) {
      throw new Error('WebMonitorSDK: appId is required');
    }
    if (!config.appVersion) {
      throw new Error('WebMonitorSDK: appVersion is required');
    }
    if (!config.endpoint) {
      throw new Error('WebMonitorSDK: endpoint is required');
    }

    // 验证采样率范围
    if (config.sampleRate !== undefined && (config.sampleRate < 0 || config.sampleRate > 1)) {
      console.warn('WebMonitorSDK: sampleRate should be between 0 and 1, setting to 1');
      config.sampleRate = 1;
    }

    return { ...defaultConfig, ...config } as MonitorConfig;
  }

  /**
   * 设置数据采集器
   */
  private setupCollectors(): void {
    // 错误采集器
    const errorCollector = new ErrorCollector(this.eventBus, this.config);
    this.collectors.set('error', errorCollector);
    errorCollector.start();

    // 性能采集器
    const performanceCollector = new PerformanceCollector(this.eventBus, this.config);
    this.collectors.set('performance', performanceCollector);
    performanceCollector.start();

    // 网络采集器
    const networkCollector = new NetworkCollector(this.eventBus, this.config);
    this.collectors.set('network', networkCollector);
    networkCollector.start();

    // 用户行为采集器
    const behaviorCollector = new BehaviorCollector(this.eventBus, this.config);
    this.collectors.set('behavior', behaviorCollector);
    behaviorCollector.start();

    if (this.config.enableDebug) {
      console.log('WebMonitorSDK: Collectors setup completed');
      console.log('Active collectors:', Array.from(this.collectors.keys()));
    }
  }

  /**
   * 设置事件监听器
   */
  private setupEventListeners(): void {
    // 监听所有采集的事件并进行统一处理
    this.eventBus.on('event', (eventData: any) => {
      const monitorEvent: MonitorEvent = {
        type: eventData.type || EventType.CUSTOM,
        timestamp: eventData._meta?.timestamp || Date.now(),
        sessionId: this.sessionId,
        userId: this.config.userId,
        data: eventData,
        context: getEventContext()
      };

      // 应用采样率
      if (Math.random() <= this.config.sampleRate) {
        if (this.config.enableDebug) {
          console.log('WebMonitorSDK: Processing event', monitorEvent);
        }
        
        // 上报事件
        if (this.reporter) {
          this.reporter.report(monitorEvent);
        }
      }
    });

    // uni-app 环境兼容的页面生命周期监听
    this.setupPageLifecycleListeners();
  }

  /**
   * 设置页面生命周期监听器 (uni-app兼容)
   */
  private setupPageLifecycleListeners(): void {
    // #ifdef H5
    if (typeof window !== 'undefined') {
      // 页面卸载时立即上报
      window.addEventListener('beforeunload', () => {
        this.flush().catch(err => {
          if (this.config.enableDebug) {
            console.error('WebMonitorSDK: flush on beforeunload failed', err);
          }
        });
      });

      // 页面可见性变化时上报
      if (typeof document !== 'undefined') {
        document.addEventListener('visibilitychange', () => {
          if (document.visibilityState === 'hidden') {
            this.flush().catch(err => {
              if (this.config.enableDebug) {
                console.error('WebMonitorSDK: flush on visibilitychange failed', err);
              }
            });
          }
        });
      }
    }
    // #endif

    // #ifdef MP
    // 小程序环境的生命周期监听
    if (typeof uni !== 'undefined') {
      // 监听小程序隐藏
      uni.onAppHide(() => {
        this.flush().catch(err => {
          if (this.config.enableDebug) {
            console.error('WebMonitorSDK: flush on app hide failed', err);
          }
        });
      });
    }
    // #endif
  }

  // ========== 公共 API 方法 ==========

  /**
   * 通用事件追踪
   */
  public track(event: Partial<MonitorEvent>): void {
    if (!this.initialized) {
      console.warn('WebMonitorSDK: not initialized');
      return;
    }

    // 使用统一事件总线发送事件
    this.eventBus.emit('event', {
      type: event.type || EventType.CUSTOM,
      data: event.data,
      timestamp: event.timestamp || Date.now()
    });

    if (this.config.enableDebug) {
      console.log('WebMonitorSDK: track event', event);
    }
  }

  /**
   * 错误追踪
   */
  public trackError(error: Error | string, extra?: any): void {
    const errorData: ErrorEventData = {
      message: error instanceof Error ? error.message : error,
      stack: error instanceof Error ? error.stack : undefined,
      source: 'js',
      ...extra
    };

    this.track({
      type: EventType.ERROR,
      data: errorData
    });
  }

  /**
   * API请求追踪
   */
  public trackApi(data: any): void {
    this.track({
      type: EventType.API,
      data
    });
  }

  /**
   * 性能数据追踪
   */
  public trackPerformance(data: any): void {
    this.track({
      type: EventType.PERFORMANCE,
      data
    });
  }

  /**
   * 用户行为追踪
   */
  public trackBehavior(data: any): void {
    this.track({
      type: EventType.BEHAVIOR,
      data
    });
  }

  /**
   * 自定义事件追踪
   */
  public trackCustom(data: CustomEventData): void {
    this.track({
      type: EventType.CUSTOM,
      data
    });
  }

  /**
   * 便捷的自定义事件追踪方法 (兼容原API)
   */
  public trackCustomEvent(eventName: string, data?: any): void {
    this.trackCustom({
      name: eventName,
      value: data
    });
  }

  /**
   * 设置用户ID
   */
  public setUserId(userId: string): void {
    if (!this.initialized) {
      console.warn('WebMonitorSDK: not initialized');
      return;
    }
    this.config.userId = userId;
  }

  /**
   * 设置元数据
   */
  public setMetadata(metadata: Record<string, any>): void {
    if (!this.initialized) {
      console.warn('WebMonitorSDK: not initialized');
      return;
    }
    this.config.metadata = { ...this.config.metadata, ...metadata };
  }

  /**
   * 立即上报数据
   */
  public async flush(): Promise<void> {
    if (!this.initialized || !this.reporter) {
      return;
    }

    try {
      if (this.reporter) {
        await this.reporter.flush(true);
      }
      if (this.config.enableDebug) {
        console.log('WebMonitorSDK: flush completed');
      }
    } catch (error) {
      if (this.config.enableDebug) {
        console.error('WebMonitorSDK: flush failed', error);
      }
    }
  }

  /**
   * 销毁SDK实例
   */
  public destroy(): void {
    if (!this.initialized) {
      return;
    }

    // 停止所有采集器
    this.collectors.forEach(collector => {
      if (collector && typeof collector.stop === 'function') {
        collector.stop();
      }
    });
    this.collectors.clear();

    // 停止上报器
    if (this.reporter) {
      this.reporter.stop();
    }

    // 清理事件监听器
    this.eventBus.clear();

    // 最后上报
    this.flush().finally(() => {
      this.initialized = false;
      if (this.config.enableDebug) {
        console.log('WebMonitorSDK: destroyed');
        console.log('Final EventBus stats:', this.eventBus.getEventStats());
      }
    });
  }

  /**
   * 获取当前配置 (调试用)
   */
  public getConfig(): MonitorConfig | undefined {
    return this.config;
  }

  /**
   * 获取会话ID
   */
  public getSessionId(): string {
    return this.sessionId;
  }

  /**
   * 获取采集器状态 (调试用)
   */
  public getCollectorsStatus(): Record<string, any> {
    const status: Record<string, any> = {};
    this.collectors.forEach((collector, name) => {
      if (collector && typeof collector.getStatus === 'function') {
        status[name] = collector.getStatus();
      } else {
        status[name] = { name, active: true };
      }
    });
    return status;
  }

  /**
   * 获取上报器状态 (调试用)
   */
  public getReporterStatus(): any {
    return this.reporter?.getStatus() || { isStarted: false };
  }


}

// 导出单例接口
export const webMonitor = WebMonitorSDK.getInstance(); 